<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:fo="http://www.w3.org/1999/XSL/Format"
	xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
			 xmlns:s="http://www.w3.org/2001/XMLSchema"
			 xmlns:s0="http://tempuri.org/" 
			 xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
			 xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/"
			 xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/">
  <xsl:variable name="service.name" select="//*[local-name()='service']/@name"/>
	<xsl:variable name="service.endpoint" select="//*[local-name()='service']/*[local-name()='port']/*[local-name()='address']/@location"/>
	<xsl:variable name="service.namespace" select="//*[local-name()='schema']/@targetNamespace"/>
  <xsl:variable name="service.prefix" select="substring-before(//*[local-name()='binding']/@type,':')"/>

	<xsl:output method="text"/>
<!--    
var EspConnector = {
	create : function ()
	{
		return {
			deserialize  : deserialize,
			envelope     : envelope,
			invoke       : invoke,
			endpoint     : 'http://www.101stratford.com/webservices/esp/connector.php',
			namespace    : 'http://www.cyber8.net/webservices',
			GetContactRequest :  function (id)
			{
				var request="<GetContact xmlns=\"" + this.namespace + "\">"; 
				request+=Cdata ('id', id);
				request+="</GetContact>";
				return request;        
			},
			GetContact :  function (id)
			{
				var request=this.GetContactRequest (id);
				return this.invoke (request, "GetContactResult", this.namespace + "/GetContact", false, Contact);
			},
			GetContactAsync : function (id)
			{
				var request=this.GetContactRequest (id);
				return this.invoke (request, "GetContactResult", this.namespace + "/GetContact", false, Contact, this.GetContactCompleted);
			},
			GetContactCompleted : function (sender, e)
			{ // add your handler code for this event
				alert (e.Result);
			} 			
		}
	}
};
	-->
<xsl:template match="/"> 	

var Cdata = function (name, value)
{
    return '&lt;'+name+'&gt;&lt;![CDATA['+value+']]&gt;&lt;/'+name+'&gt;';
};
var Read = function (element) { return element.firstChild?element.firstChild.nodeValue:element.nodeValue; };

var invoke = function (data, nodename, action, array, proxy, callback) // invoke                                                                                                                                                                                                                                                                               
{
    var mhttp=XmlHttp.create();//new ActiveXObject("Msxml2.XMLHTTP");                                                                                                                                                                                                                                                                      
    mhttp.open("POST", this.endpoint, callback ? true : false);    
    mhttp.setRequestHeader('SOAPAction',action);
    window.asyncontroller=this;
    if (callback)
    {                                                                                                                                                                                                
        mhttp.onreadystatechange = function ()                                              
        {                                              
            if (mhttp.readyState == 4)                                              
            {    
                var args = new EspConnectorEventArgs ();
                args.State = mhttp.status;
                if (mhttp.status==200)
                {
                    args.Result=window.asyncontroller.deserialize (mhttp.responseText, nodename, proxy);  
                }
                else
                {
                    args.Error = "URL responded with an error";
                }
                callback (window.asyncontroller, args);                                              
            }  
        }                                          
    }
    mhttp.send( this.envelope(data) );       
    if (callback) return true;        
    var result=this.deserialize (mhttp.responseText, nodename, proxy); 
    return array ? result : result[0];    
} // invoke  

var deserialize = function (data, nodename, proxy)
{
    var mdom=XmlDocument.create(); 
    var result=new Array();
    if (mdom.loadXML (data))
    { 
        var nodes = mdom.getElementsByTagName(nodename); 
        for (var i=0;i&lt;nodes.length;i++)
        { 
            if (proxy)
            { 
                var tmp_proxy=proxy.create();
                tmp_proxy.deserialize (nodes[i]);
                result[result.length]=tmp_proxy;     
            } else result[result.length]=Read(nodes[i]);         
        }
    } else alert ("The response was not well-formed XML.\n"+data);
    return result;
};

var envelope = function (data)
{
    var output='';
    output+='&lt;soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"';  
    output+=' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"';  
    output+=' xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;';                            
    output+='&lt;soap:Body&gt;' + data;  

    output+='&lt;/soap:Body&gt;';  
    output+='&lt;/soap:Envelope&gt;';  
    return output;
};
 


<!--function <xsl:value-of select="$service.name"/> ()-->
var <xsl:value-of select="$service.name"/> = {
    create : function ()
    {
        return {
<xsl:apply-templates select="//*[local-name()='portType']"/>
            deserialize  : deserialize,
            envelope     : envelope,
            invoke       : invoke,
            endpoint     : '<xsl:value-of select="$service.endpoint"/>',
            namespace    : '<xsl:value-of select="$service.namespace"/>'  
        }
    }
}
	
function <xsl:value-of select="$service.name"/>EventArgs (a_result, a_state, a_error)
{
    this.Result=a_result;
    this.State=a_result;
    this.Error=a_error;
}

<xsl:apply-templates select="//*[local-name()='schema']/*[local-name()='complexType']"/>
<xsl:apply-templates select="//*[local-name()='schema']/*[local-name()='simpleType']"/>
</xsl:template>

 
<xsl:template name="harness">
<xsl:param name="for"/>
<xsl:param name="me" select="$for[1]"/>
<xsl:param name="next" select="$for[position()!=1]"/>
<xsl:variable name="name" select="$me/@name"/>
<xsl:value-of select="$name"/> : [<xsl:call-template name="harness.args">
<xsl:with-param name="for" select="//*[local-name()='element'][@name=$name]/*[local-name()='complexType']/*[local-name()='sequence']/*[local-name()='element']"/>
</xsl:call-template>],


<xsl:if test="$next"> 
<xsl:call-template name="harness">
<xsl:with-param name="for" select="$next"/>
</xsl:call-template></xsl:if> 
</xsl:template>

<xsl:template name="harness.args">
	<xsl:param name="for"/>
	<xsl:param name="me" select="$for[1]"/>
	<xsl:param name="next" select="$for[position()!=1]"/>'<xsl:value-of select="$me/@name"/>' <xsl:if test="$next">, <xsl:call-template name="harness.args">
<xsl:with-param name="for" select="$next"/>
</xsl:call-template></xsl:if> 
</xsl:template>


<xsl:template match="//*[local-name()='element']">
	<xsl:for-each select="./*[local-name()='complexType']/*[local-name()='sequence']/*[local-name()='element']">
		<xsl:value-of select="@name"/> <xsl:if test="following-sibling::*[local-name()='element']">, </xsl:if>
	</xsl:for-each>
</xsl:template>


	<xsl:template match="//*[local-name()='operation']">
		<xsl:variable name="name" select="@name"/>
    <xsl:variable name="soapaction" select="//*[local-name()='operation'][@name=$name]/*[local-name()='operation'][@soapAction]/@soapAction"/>
		<xsl:variable name="response" select="//*[local-name()='element'][@name=concat($name,'Response')]"/>
		<xsl:variable name="type" select="$response/*[local-name()='complexType']/*[local-name()='sequence']/*[local-name()='element']"/>
		<xsl:variable name="type.name">
			<xsl:choose>
				<xsl:when test="contains($type/@type,':')">
					<xsl:value-of  select="substring-after($type/@type,':')"/>
				</xsl:when>
				<xsl:otherwise>
					<xsl:value-of select="$type/@type"/>
				</xsl:otherwise>
			</xsl:choose>
		</xsl:variable>
    <xsl:variable name="type.proxy">
      <xsl:choose>
        <xsl:when test="substring-before($type/@type,':')=$service.prefix"><xsl:value-of select="$type.name"/></xsl:when>
        <xsl:otherwise>false</xsl:otherwise>
      </xsl:choose>
    </xsl:variable>
		<xsl:variable name="type.max">
			<xsl:choose>
				<xsl:when test="$type/@maxOccurs='unbounded'">true</xsl:when>
				<xsl:otherwise>false</xsl:otherwise>
			</xsl:choose>
		</xsl:variable> 
<xsl:if test="not (preceding::*[local-name()='operation'][@name=$name])">
    // <xsl:value-of select="@name"/> methods 
            <xsl:value-of select="@name"/>Request : function (<xsl:apply-templates select="//*[local-name()='element'][@name=$name]"/>)
            {
                var request="&lt;<xsl:value-of select="@name"/> xmlns=\"" + this.namespace + "\"&gt;";<xsl:call-template name="form.invoke">
	<xsl:with-param name="method" select="@name"/>
</xsl:call-template>
                request+="&lt;/<xsl:value-of select="@name"/>&gt;";
                return request;        
            },    
            <xsl:value-of select="@name"/> : function (<xsl:apply-templates select="//*[local-name()='element'][@name=$name]"/>)
            {
                var request=this.<xsl:value-of select="@name"/>Request (<xsl:apply-templates select="//*[local-name()='element'][@name=$name]"/>);
                return this.invoke (request, "<xsl:value-of select="@name"/>Result", "<xsl:value-of select="$soapaction"/>", <xsl:value-of select="$type.max"/>, <xsl:value-of select="$type.proxy"/>);
            },    
            <xsl:value-of select="@name"/>Async : function (<xsl:apply-templates select="//*[local-name()='element'][@name=$name]"/>)
            {
                var request=this.<xsl:value-of select="@name"/>Request (<xsl:apply-templates select="//*[local-name()='element'][@name=$name]"/>);
                return this.invoke (request, "<xsl:value-of select="@name"/>Result", "<xsl:value-of select="$soapaction"/>", <xsl:value-of select="$type.max"/>, <xsl:value-of select="$type.proxy"/>, this.<xsl:value-of select="@name"/>Completed);
            },    
            <xsl:value-of select="@name"/>Completed : function (sender, e)
            { // add your handler code for this event
                alert (e.Result);
            }, 
</xsl:if>
		
	</xsl:template>

	
<xsl:template name="form.invoke">
	<xsl:param name="method"/>
	<xsl:param name="for" select="//*[local-name()='element'][@name=$method]/*[local-name()='complexType']/*[local-name()='sequence']/*[local-name()='element']"/>
	<xsl:param name="me" select="$for[1]"/>
	<xsl:param name="next" select="$for[position()!=1]"/><xsl:if test="$me"> 
                request+=Cdata ('<xsl:value-of select="$me/@name"/>', <xsl:value-of select="$me/@name"/>);<xsl:if test="$next">
<xsl:call-template name="form.invoke">
<xsl:with-param name="for" select="$next"/>
</xsl:call-template>
	</xsl:if></xsl:if>
</xsl:template>

	<xsl:template match="//*[local-name()='portType']">

		<xsl:apply-templates select="./*[local-name()='operation']">
		</xsl:apply-templates>
	</xsl:template>


  <xsl:template match="//*[local-name()='schema']/*[local-name()='complexType']"> 
var <xsl:value-of select="@name"/> = {
    create : function ()
    {
        return {
            <xsl:for-each select="./*/*[local-name()='element']">
            <xsl:value-of select="@name"/>:<xsl:choose>
            <xsl:when test="@maxOccurs='unbounded'">[]</xsl:when>
            <xsl:otherwise>null</xsl:otherwise></xsl:choose>,
            </xsl:for-each>
            deserialize:function(element)
            {
                for (var x=0;x&lt;element.childNodes.length;x++)
                {
                    var child = element.childNodes[x];
                    var value = Read(child); 
                    if (value) this[child.nodeName] = value; 
                }
            }
        }
    }
}

</xsl:template>


  <xsl:template name="enum.list"> 
	<xsl:param name="for"/>
	<xsl:param name="name"/>
	<xsl:param name="index">0</xsl:param>
	<xsl:param name="me" select="$for[1]"/>
	<xsl:param name="next" select="$for[position()!=1]"/>
<xsl:value-of select="$name"/>.<xsl:value-of select="$me/@value"/>=<xsl:value-of select="$index"/>;
<xsl:if test="$next">
<xsl:call-template name="enum.list">
<xsl:with-param name="for" select="$next"/>
<xsl:with-param name="name" select="$name"/>
<xsl:with-param name="index" select="$index+1"/>
</xsl:call-template>
	</xsl:if>
</xsl:template>


  <xsl:template match="//*[local-name()='schema']/*[local-name()='simpleType']"> 
var <xsl:value-of select="@name"/>={};
<xsl:call-template name="enum.list">
<xsl:with-param name="for" select="./*/*[local-name()='enumeration']"/>
<xsl:with-param name="name" select="@name"/> 
</xsl:call-template>
<!--<xsl:value-of select="@name"/>=new <xsl:value-of select="@name"/>Interface();
<xsl:value-of select="@name"/>Interface = function()
{<xsl:for-each select="./*/*[local-name()='enumeration']">
    this.<xsl:value-of select="@value"/>="<xsl:value-of select="@value"/>";</xsl:for-each> 
}

-->

</xsl:template>



</xsl:stylesheet> 
